package com.surpassun.emall.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.surpassun.emall.exception.NoSuchStoreException;
import com.surpassun.emall.form.StoreForm;
import com.surpassun.emall.model.Address;
import com.surpassun.emall.model.Province;
import com.surpassun.emall.model.Store;
import com.surpassun.emall.model.StoreType;
import com.surpassun.emall.model.User;
import com.surpassun.emall.service.CacheService;
import com.surpassun.emall.service.StoreService;
import com.surpassun.emall.service.StoreTypeService;
import com.surpassun.emall.service.UserService;
import com.surpassun.emall.util.CacheUtil;
import com.surpassun.emall.util.Constants;
import com.surpassun.emall.util.ParamUtil;
import com.surpassun.emall.util.Validator;

@Controller
@RequestMapping("/store/**")
public class StoreController {
	
	private Logger _log = LoggerFactory.getLogger(StoreController.class);
	private static final String ATTR_ADD_STORE_ERROR = "addStoreError";
	
	@Inject
	StoreService storeService;
	
	@Inject
	StoreTypeService storeTypeService;
	
	@Inject
	UserService userService;
	
	@Inject
	CacheService cacheService;
	
	@Inject
	MessageSource messageSource;
	
	@RequestMapping
	public String view(HttpServletRequest request) {
		return "view";
	}
	
	@RequestMapping("/store/create")
	public String createStore(HttpServletRequest request, Model model) {
		String from = ParamUtil.getString(request, Constants.ATTR_EDIT_STORE_FROM, Constants.ATTR_USER);
		model.addAttribute(Constants.ATTR_ADD_STORE, true);
		
		StoreForm storeForm = new StoreForm();
		storeForm.setFrom(from);
		initStoreForm(storeForm, request.getLocale());
		model.addAttribute(Constants.ATTR_STORE, storeForm);
		
		return "editStore";
	}

	@RequestMapping("/store/edit")
	public String editStore(HttpServletRequest request, Model model, @RequestParam(required=true) long storeId) {
		Store store = storeService.get(storeId);
		if (Validator.isNotNull(store)) {
			String from = ParamUtil.getString(request, Constants.ATTR_EDIT_STORE_FROM, Constants.ATTR_USER);
			model.addAttribute(Constants.ATTR_ADD_STORE, false);
			
			StoreForm storeForm = null;
			if (model.containsAttribute(Constants.ATTR_STORE)) {
				storeForm = (StoreForm)model.asMap().get(Constants.ATTR_STORE);
			} else {
				storeForm = new StoreForm();
				storeForm.setFrom(from);
				storeForm.setStoreId(store.getId());
				storeForm.setName(store.getName());
				storeForm.setStoreTypeId(store.getType().getId());
				storeForm.setOwnerId(store.getOwner().getId());
				storeForm.setStreet(store.getAddress().getStreet());
				storeForm.setComplememt(store.getAddress().getComplememt());
				storeForm.setPostCode(store.getAddress().getPostCode());
				storeForm.setCityId(store.getAddress().getCityId());
				storeForm.setProvinceId(store.getAddress().getProvinceId());
				storeForm.setCountryId(store.getAddress().getCountryId());
				initStoreForm(storeForm, request.getLocale());
				model.addAttribute(Constants.ATTR_STORE, storeForm);
			}
			return "editStore";
		} else {
			return "adminStore";
		}
	}
	
	@RequestMapping("/store/save")
	public String saveStore(HttpServletRequest request, @ModelAttribute(value = Constants.ATTR_STORE) @Valid StoreForm storeForm,
			Model model) {
		StoreType type = storeTypeService.get(storeForm.getStoreTypeId());
		Address address = new Address(storeForm.getCountryId(), storeForm.getProvinceId(), storeForm.getCityId(),
				storeForm.getPostCode(), storeForm.getStreet(), storeForm.getComplememt());
		User owner = userService.get(storeForm.getOwnerId());
		if (storeForm.getStoreId() == 0) {
			//create new store
			storeService.addStore(storeForm.getName(), type, address, owner);
			_log.info("New store added, name : " + storeForm.getName() + ", owner : " + owner.getFullname());
		} else {
			//update store
			try {
				storeService.updateStore(storeForm.getStoreId(), storeForm.getName(), type, address, owner);
				_log.info("Store updated, name : " + storeForm.getName() + ", owner : " + owner.getFullname());
			} catch (NoSuchStoreException nsse) {
				_log.error("No such store found with ID : " + storeForm.getStoreId());
				model.addAttribute(ATTR_ADD_STORE_ERROR, "admin.store.add.error");
			}
		}
		return "adminStore";
	}
	
	@SuppressWarnings("unchecked")
	private void initStoreForm(StoreForm storeForm, Locale Locale) {
		//set store type list
		List<StoreType> storeTypeList = (List<StoreType>)CacheUtil.getCache().get(Constants.ATTR_STORE_TYPES);
		Map<Long, String> storeTypes = new HashMap<Long, String>();
		for (StoreType type : storeTypeList) {
			storeTypes.put(type.getId(), messageSource.getMessage(type.getTypeName(), null, Locale));
		}
		storeForm.setStoreTypes(storeTypes);
		
		//set owner list
		storeForm.setUsers(cacheService.getUserList());
		
		//set country list
		storeForm.setCountries(cacheService.getCountryList());

		//set province list
		List<Province> provinces = (List<Province>)CacheUtil.getObject(Constants.ATTR_PROVINCES);
		storeForm.setProvinces(provinces);
		
		//set city list
		storeForm.setCities(cacheService.getCityList());
	}
}
